/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package util.file;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.Reader;
import util.patron.command.Command2;

/**
 *
 * @author Rdelacruz
 */
public class FileUtil {
  
/*    
Ejemplos de separadores    
//http://www.journaldev.com/851/java-file-separator-separatorchar-pathseparator-pathseparatorchar-explained-with-example    
//Unix system
File.separator  = / 
File.separatorChar = /
File.pathSeparator = :
File.pathSeparatorChar  = :

Windows system
File.separator  = \
File.separatorChar  = \
File.pathSeparator  = ;
File.pathSeparatorChar  = ;
*/
    
    public static final String SEPARADOR = File.separator;
    public static final String SEPARADOR_RUTA = File.pathSeparator;
    public static final String SALTO_LINEA = System.getProperty("line.separator");
    
    public static String fileToString(File file, Command2<StringBuilder,String> operador ) throws Exception {
    	return readerToString(new FileReader(file),operador);    	
    }
    
    //http://www.mkyong.com/java/how-to-convert-inputstream-to-string-in-java/
    private static String readerToString(Reader reader, Command2<StringBuilder,String> comando ) throws Exception { 
        BufferedReader br = null;
        StringBuilder sb = new StringBuilder();
        String linea;
        try {
            br = new BufferedReader(reader);
            while ((linea = br.readLine()) != null) {
                comando.execute(sb,linea);
            }
        } 
        finally {
            if(br != null) br.close();
            if(reader!=null) reader.close();
        }
        return sb.toString();
    }
    
    private static String readerToString(Reader reader) throws IOException { 
        BufferedReader br = null;
        StringBuilder sb = new StringBuilder();
        String linea;
        try {
            br = new BufferedReader(reader);
            while ((linea = br.readLine()) != null) {
                sb.append(linea);
            }
        } 
        finally {
            if(br != null) br.close();  
            if(reader!=null) reader.close();
        }
        return sb.toString();
    }
    
    
    //http://www.programcreek.com/2011/11/java-convert-a-file-into-a-string/
    public static String fileToString(File file) throws IOException { 
        return readerToString(new FileReader(file));
    }
    
    //http://www.baeldung.com/convert-file-to-input-stream
    public static InputStream fileToInputStream(File file) throws FileNotFoundException {
        return new FileInputStream(file);
    }
    
    //http://www.mkyong.com/java/how-to-convert-inputstream-to-string-in-java/
    public static String inputStreamtoString(InputStream is) throws IOException {         
        return readerToString(new InputStreamReader(is));
    }
    
       /**
     * 
     * @param url
     * @return true: si fue borrado
     */
    public static boolean deleteIfExists(String url) {
        File file = new File(url);
        if(file.exists())
            return file.delete();
        
        return false;
    }
    
    public static String getUrl(File file) {
        return file.getPath();
        //return file.getAbsolutePath();
    }
    
    public static String getNombre(File file) {
        return file.getName();
    }
    
    public static String getDirectorio(File file) {
        return file.getParent();
    }
    
    public static File getDirectorioFile(File file) {
        return file.getParentFile();
    }
    
        /**
     * Recursive Method to generate a FileName in the same
     * Folder as the {@code inputFile}, that is not existing
     * and ends with {@code _temp}.
     * 
     * @param inputFile
     *            The FileBase to generate a Tempfile
     * @return A non existing File
     */
    //http://stackoverflow.com/questions/14400030/is-there-an-operation-to-move-and-overwrite-files
    public static File getNonExistingTempFile(File inputFile) {
        File tempFile = new File(inputFile.getParentFile(), inputFile.getName() + "_temp");
        if (tempFile.exists()) {
            return getNonExistingTempFile(tempFile);
        } else {
            return tempFile;
        }
    }
    
    //http://stackoverflow.com/questions/6994518/how-to-delete-the-content-of-text-file-without-deleting-itself
    public static void limpiarContenidoArchivo(File archivo) throws FileNotFoundException {
        PrintWriter writer = new PrintWriter(archivo);
        writer.print("");//reemplaza su contenido con ""
        writer.close();
    }
    
    //Obtiene los recursos del "default package"
    public static InputStream getResourceAsStreamFromDefaultPackage(String ruta) {
        return Thread.currentThread().getContextClassLoader().getResourceAsStream(ruta);
    }
    
    public static String replaceInFileToString(File file, String expresion, String reemplazo) throws IOException { 
        return replaceInReaderToString(new FileReader(file), expresion, reemplazo);
    }
    
    public static String replaceInStreamToString(InputStream is, String expresion, String reemplazo) throws IOException { 
        if(is==null)
            return null;
        return replaceInReaderToString(new InputStreamReader(is), expresion, reemplazo);
    }
    
    public static String replaceInReaderToString(Reader reader, String expresion, String reemplazo) throws IOException {
        BufferedReader br = null;
        StringBuilder sb = new StringBuilder();
        String line;
        try {
            br = new BufferedReader(reader);
            while ((line = br.readLine()) != null) {
                sb.append(line.replace(expresion, reemplazo));
                sb.append(SALTO_LINEA);
            }
        } 
        finally {
            if (br != null) br.close();                
        }
        return sb.toString();
    }
    
    
    
      
        
    public static String replaceInFileToString(String pathname, String expresion, String reemplazo) throws FileNotFoundException, IOException {
        
        //File inFile = new File(pathname);
        //if (!inFile.isFile()) {//si no es archivo
        //  return null;
        //}
        
        StringBuilder sb = new StringBuilder();
        BufferedReader br = null;
        try {
            br = new BufferedReader(new FileReader(pathname));
            String line; 
            while ((line = br.readLine()) != null) {
                sb.append(line.replace(expresion, reemplazo));
                sb.append(SALTO_LINEA);
            }
        }
        finally {
            if(br!=null) br.close();    
        }
        
        return sb.toString();
    }
    
    
    public static boolean crearDirectorioSiNoExiste(String directorioNombre, boolean lanzarExcepcionSiNoSePuede) throws RuntimeException{
        File dir = new File(directorioNombre);                    
        return crearDirectorioSiNoExiste(dir,lanzarExcepcionSiNoSePuede);
    }
    
    public static boolean crearDirectorioSiNoExiste(File directorio, boolean lanzarExcepcionSiNoSePuede) throws RuntimeException{
        if (!existeDirectorio(directorio)) {
            if (directorio.mkdirs()) {//DIRECTORIO CREADO                                   
                return true;
            }
            else {
            	if(lanzarExcepcionSiNoSePuede)
                    throw new RuntimeException("No se pudo crear el directorio "+directorio+". Tal vez falten permisos de escritura.");
            }
        }
        return false;
    }    
        
    public static boolean existeDirectorio(File directorio) throws RuntimeException {
        if (directorio.exists()) {
            if (directorio.isDirectory()) {
                return true;
            }
            else {
                RuntimeException e = new RuntimeException("La URL '" + directorio.getPath()+ "' no corresponde a un directorio");
                throw e;            
            }
        }  
        //else {
        //    throw new RuntimeException("No existe el directorio '"+ directorioNombre+"'");
        //}
        return false;
    }    
        
    
    public static void escribirArchivo(String archivo, String data) throws FileNotFoundException {
        PrintWriter writer = new PrintWriter(new File(archivo));
        writer.print(data);
        writer.close();
    }
    
    public static void escribirArchivo(String archivo, byte data[]) throws FileNotFoundException {
        PrintWriter writer = new PrintWriter(new File(archivo));
        writer.print(data);
        writer.close();
    }
    
    public File[] getArchivosContenidosEnDirectorio(File dir) {
        return dir.listFiles();
    }
 
}
